<?php

declare(strict_types=1);


namespace App\Utils\Upload;


use App\Exception\BusinessException;
use App\Task\MongoTask;
use App\Utils\Log;
use Hyperf\HttpMessage\Upload\UploadedFile;
use Hyperf\Server\Exception\RuntimeException;
use MongoDB\GridFS\Bucket;

class Upload
{
    private $id;

    private $image;

    /**
     * @var UploadedFile
     */
    public $file;

    private $validator;


    /**
     * Upload constructor.
     * @param UploadedFile $file
     * @param array $allowOptions
     */
    public function __construct(UploadedFile $file, array $allowOptions = [])
    {
        $this->file = $file;
        $this->validator = make(Validator::class, [$allowOptions]);
    }

    public function validated(): bool
    {
        return $this->validator->validated($this->file);

    }

    public function store()
    {
        $conn = di(MongoTask::class)->manager();//如果设置了密码自己配置DSN
        $grid = new Bucket($conn, 'sy_task');
        $size = $this->file->getSize();
        $md5 = md5_file($this->file->getPathname());

        //保存新上传的文件
        $exists = $grid->findOne(array('md5' => $md5, 'length' => $size), array('md5'));
        if (empty($exists)) {
            try {
                $grid->uploadFromStream($md5, fopen($this->file->getPathname(), 'r'), [
                    'contentType'  => $this->file->getMimeType(),
                    'aliases' => [
                        'origin_name' => $this->file->getClientFilename()
                    ]
                ]);
            } catch (\Throwable $e) {
                Log::get()->error($e->getTraceAsString());
                throw new RuntimeException('File upload failed');
            }
        } else {
            unlink($this->file->getPathname());
        }
        $this->setID($md5);
        $this->setImage($md5);
        return $this;
    }

    public function setID(string $md5)
    {
        return $this->id = $md5;
    }

    public function setImage(string $md5)
    {
        return $this->image = di(View::class)->fullPath($md5);
    }

    /**
     * @return mixed
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @return mixed
     */
    public function getImage()
    {
        return $this->image;
    }
}